package com.danjinwulian.web.controller.iot;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.danjinwulian.common.constant.CacheConstants;
import com.danjinwulian.common.core.domain.entity.*;
import com.danjinwulian.common.utils.file.ImageUtils;
import com.danjinwulian.iot.service.TencentIotService;
import com.danjinwulian.common.annotation.Log;
import com.danjinwulian.common.constant.IoTConstants;
import com.danjinwulian.common.core.controller.BaseController;
import com.danjinwulian.common.core.domain.AjaxResult;
import com.danjinwulian.common.core.page.TableDataInfo;
import com.danjinwulian.common.core.redis.RedisCache;
import com.danjinwulian.common.enums.BusinessType;
import com.danjinwulian.common.utils.StringUtils;
import com.danjinwulian.common.utils.Threads;
import com.danjinwulian.device.service.*;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.UploadManager;
import com.qiniu.util.Auth;
import com.qiniu.util.UrlSafeBase64;
import com.tencentcloudapi.iotexplorer.v20190423.models.*;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 * 腾讯云物联网设备管理控制器
 * 基于腾讯云物联网开发平台API实现设备管理功能
 *
 * @author ken.h
 */
@RestController
@RequestMapping("/device/device")
public class IotDeviceController extends BaseController
{
    @Autowired
    private IIotDeviceService deviceService;
    @Autowired
    private IIotProductService productService;
    @Autowired
    private IIotHotelService hotelService;
    @Autowired
    private IIotTenantService tenantService;
    @Autowired
    private IIotTenantPowerService tenantPowerService;
    @Autowired
    private IMpWeixinService weixinService;
    @Autowired
    private TencentIotService tencentIotService;

    @Value("${weixin.danjinwulian.appid}")
    private String danjinIotAppId;
    @Value("${weixin.danjinwulian.secret}")
    private String danjinIotSecret;

    @Value("${qiniu.accessKey}")
    private String qiniuAccessKey;
    @Value("${qiniu.secretKey}")
    private String qiniuSecretKey;
    @Value("${qiniu.bucket}")
    private String qiniuBucket;
    @Value("${qiniu.domain}")
    private String qiniuDomain;

    @Autowired
    private RedisCache redisCache;

    /**
     * 获取设备列表
     */
    @PreAuthorize("@ss.hasPermi('device:device:list')")
    @GetMapping("/list")
    public TableDataInfo list(IotDevice device)
    {
        startPage();
        List<IotDevice> list = deviceService.selectDeviceList(device);
        TableDataInfo result = getDataTable(list);
        result.setProducts(productService.selectProductList(new IotProduct()));
        result.setHotels(hotelService.selectIotHotelList(new IotHotel()));
        return result;
    }

    /**
     * 根据设备ID获取设备信息
     */
    @PreAuthorize("@ss.hasPermi('device:device:query')")
    @GetMapping(value = { "/", "/{deviceId}" })
    public AjaxResult getInfo(@PathVariable(value = "deviceId", required = false) Long deviceId)
    {
        AjaxResult ajax = AjaxResult.success();
        if (StringUtils.isNotNull(deviceId))
        {
            IotDevice iotDevice = deviceService.selectDeviceById(deviceId);
            ajax.put(AjaxResult.DATA_TAG, iotDevice);
        }
        return ajax;
    }

    @PreAuthorize("@ss.hasPermi('device:device:query')")
    @GetMapping(value = { "/getInfoBySn" })
    public AjaxResult getInfoBySn(String deviceName)
    {
        AjaxResult ajax = AjaxResult.success();
        if (StringUtils.isNotNull(deviceName))
        {
            IotDevice iotDevice = deviceService.selectDeviceByDeviceName(deviceName);
            ajax.put(AjaxResult.DATA_TAG, iotDevice);
            ajax.put("hotels", hotelService.selectIotHotelList(new IotHotel()));
        }
        return ajax;
    }

    /**
     * 新增设备
     */
    @PreAuthorize("@ss.hasPermi('device:device:add')")
    @Log(title = "设备管理", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@Validated @RequestBody IotDevice device)
    {
        IotProduct product = productService.selectProductById(device.getProductId());

        if (device.getDeviceCount() > 100) {
            return AjaxResult.error("只能同时批量注册设备100个");
        }
        
        if (device.getDeviceCount() == 1) {     // 单个设备注册
            try {
                //当没有输入设备名称时，使用大小写字母+数字随机生成长度为20的设备名称
                if (StringUtils.isEmpty(device.getDeviceName())) {
                    device.setDeviceName(RandomStringUtils.randomAlphanumeric(20));
                }

                // 调用腾讯云物联网开发平台创建设备
                CreateDeviceResponse response = tencentIotService.createDevice(product.getProductId(), device.getDeviceName());

                if (response.getData() != null) {
                    device.setDeviceName(response.getData().getDeviceName());
                    device.setDeviceSecret(response.getData().getDevicePsk());
                    device.setStatus(3L);
                    device.setEnableState(1L);
                    device.setCreateBy(getUsername());
                    return toAjax(deviceService.insertDevice(device));
                } else {
                    return AjaxResult.error("添加设备'" + device.getDeviceName() + "'失败，" + JSON.toJSONString(response));
                }
            } catch (Exception e) {
                return AjaxResult.error("添加设备'" + device.getDeviceName() + "'失败，" + e.getMessage());
            }
        } else {    // 批量注册设备
            try {
                // 腾讯云暂不支持批量创建设备，需要循环单个创建
                for (int i = 0; i < device.getDeviceCount(); i++) {
                    String deviceName = "";
                    //当没有输入设备名称时，使用大小写字母+数字随机生成长度为20的设备名称
                    if (StringUtils.isEmpty(device.getDeviceName())) {
                        deviceName = RandomStringUtils.randomAlphanumeric(20);
                    } else {
                        deviceName = device.getDeviceName() + "_" + (i + 1);
                    }

                    CreateDeviceResponse response = tencentIotService.createDevice(product.getProductId(), deviceName);

                    if (response.getData() != null) {
                        IotDevice applyDevice = new IotDevice();
                        applyDevice.setProductId(device.getProductId());
                        applyDevice.setDeviceName(response.getData().getDeviceName());
                        device.setDeviceSecret(response.getData().getDevicePsk());
                        applyDevice.setStatus(3L);
                        applyDevice.setEnableState(1L);
                        applyDevice.setCreateBy(getUsername());
                        deviceService.insertDevice(applyDevice);
                    }

                    // 避免请求过于频繁
                    Threads.sleep(100);
                }
                return AjaxResult.success();
            } catch (Exception e) {
                return AjaxResult.error("批量添加设备失败，" + e.getMessage());
            }
        }
    }

    /**
     * 修改设备
     */
    @PreAuthorize("@ss.hasPermi('device:device:edit')")
    @Log(title = "设备管理", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@Validated @RequestBody IotDevice device)
    {
        if (StringUtils.isNotEmpty(device.getRoomName())
                && IoTConstants.NOT_UNIQUE.equals(deviceService.checkRoomNameUnique(device)))
        {
            return AjaxResult.error("修改设备信息失败，房间名称已存在");
        }

        IotProduct product = productService.selectProductById(device.getProductId());
        if (StringUtils.isNotNull(product)) {
            IotDevice existDevice = deviceService.selectDeviceByDeviceName(device.getDeviceName());
            if (StringUtils.isNotNull(existDevice)) {
                device.setWifiName(null);
                device.setWifiPswd(null);
                device.setCtBeginTime(null);
                device.setCtEndTime(null);
                // 执行业务逻辑
                device.setUpdateBy(getUsername());
                return toAjax(deviceService.updateDevice(device));
            } else {
                return AjaxResult.error("设备不存在！");
            }
        } else {
            return AjaxResult.error("设备对应产品不存在！");
        }
    }

    /**
     * 删除设备
     */
    @PreAuthorize("@ss.hasPermi('device:device:remove')")
    @Log(title = "设备管理", businessType = BusinessType.DELETE)
    @DeleteMapping("/{deviceIds}")
    public AjaxResult remove(@PathVariable Long[] deviceIds)
    {
        AjaxResult ajax = AjaxResult.success();

        // 获取要删除的设备信息
        for (Long deviceId : deviceIds)
        {
            IotDevice device = deviceService.selectDeviceById(deviceId);
            if (StringUtils.isNotNull(device)) {
                IotProduct product = productService.selectProductById(device.getProductId());
                if (StringUtils.isNotNull(product)) {
                    try {
                        // 调用腾讯云物联网开发平台删除设备
                        DeleteDeviceResponse response = tencentIotService.deleteDevice(
                                product.getProductId(), device.getDeviceName());

                        if (response.getRequestId() != null) {
                            deviceService.deleteDeviceById(deviceId);
                        } else {
                            return AjaxResult.error("删除设备'" + device.getRoomName() + "'失败，" + JSON.toJSONString(response));
                        }
                    } catch (Exception e) {
                        return AjaxResult.error("删除设备'" + device.getRoomName() + "'失败，" + e.getMessage());
                    }
                }
            }
        }

        return ajax;
    }

    /**
     * 修改设备WiFi信息
     */
    @PreAuthorize("@ss.hasPermi('device:device:edit')")
    @Log(title = "设备管理", businessType = BusinessType.UPDATE)
    @PutMapping("/editWifi")
    public AjaxResult editWifi(@Validated @RequestBody IotDevice device)
    {
        IotProduct product = productService.selectProductById(device.getProductId());
        if (StringUtils.isNotNull(product)) {
            IotDevice existDevice = deviceService.selectDeviceByDeviceName(device.getDeviceName());
            if (StringUtils.isNotNull(existDevice)) {
                if (IoTConstants.DEVICE_ONLINE.equals(existDevice.getStatus())) {
                    try {
                        // 使用腾讯云物联网开发平台发布消息
                        Map message = new HashMap();
                        message.put("method", "wifi_attr_cmd");
                        if (StringUtils.isNotNull(device.getWifiName()) && StringUtils.isNotNull(device.getWifiPswd())) {
                            message.put("wifi_name", device.getWifiName());
                            message.put("wifi_pswd", device.getWifiPswd());
                        }

                        String topic = "$thing/down/property/" + existDevice.getProductId() + "/" + device.getDeviceName();
                        String payload = JSONObject.toJSONString(message);

                        logger.info("业务侧【" + device.getDeviceName() + "】下发【wifi_attr_cmd】消息：" + payload);

                        PublishMessageResponse response = tencentIotService.publishMessage(
                                product.getProductId(), device.getDeviceName(), topic, payload);

                        if (response.getRequestId() != null) {
                            logger.info("业务侧返回【wifi_attr_cmd】消息发送成功");

                            // 执行业务逻辑
                            device.setUpdateBy(getUsername());
                            return toAjax(deviceService.updateDevice(device));
                        } else {
                            return AjaxResult.error("更改房间WiFi信息失败，" + JSON.toJSONString(response));
                        }
                    } catch (Exception e) {
                        return AjaxResult.error("更改房间WiFi信息失败，" + e.getMessage());
                    }
                } else {
                    return AjaxResult.error("设备不在线！");
                }
            } else {
                return AjaxResult.error("设备不存在！");
            }
        } else {
            return AjaxResult.error("设备对应产品不存在！");
        }
    }

    /**
     * 修改设备长通时段
     */
    @PreAuthorize("@ss.hasPermi('device:device:edit')")
    @Log(title = "设备管理", businessType = BusinessType.UPDATE)
    @PutMapping("/editCttime")
    public AjaxResult editCttime(@Validated @RequestBody IotDevice device)
    {
        IotProduct product = productService.selectProductById(device.getProductId());
        if (StringUtils.isNotNull(product)) {
            IotDevice existDevice = deviceService.selectDeviceByDeviceName(device.getDeviceName());
            if (StringUtils.isNotNull(existDevice)) {
                if (IoTConstants.DEVICE_ONLINE.equals(existDevice.getStatus())) {
                    try {
                        // 使用腾讯云物联网开发平台发布消息
                        Map message = new HashMap();
                        message.put("method", "wifi_attr_cmd");
                        if (StringUtils.isNotNull(device.getCtBeginTime()) && StringUtils.isNotNull(device.getCtEndTime())) {
                            message.put("ctTime", device.getCtBeginTime() + "-" + device.getCtEndTime());
                        }

                        String topic = "$thing/down/property/" + existDevice.getProductId() + "/" + device.getDeviceName();
                        String payload = JSONObject.toJSONString(message);

                        logger.info("业务侧【" + device.getDeviceName() + "】下发【wifi_attr_cmd】消息：" + payload);

                        PublishMessageResponse response = tencentIotService.publishMessage(
                                product.getProductId(), device.getDeviceName(), topic, payload);

                        if (response.getRequestId() != null) {
                            logger.info("业务侧返回【wifi_attr_cmd】消息发送成功");

                            // 执行业务逻辑
                            device.setUpdateBy(getUsername());
                            return toAjax(deviceService.updateDevice(device));
                        } else {
                            return AjaxResult.error("更改房间长通时段失败，" + JSON.toJSONString(response));
                        }
                    } catch (Exception e) {
                        return AjaxResult.error("更改房间长通时段失败，" + e.getMessage());
                    }
                } else {
                    return AjaxResult.error("设备不在线！");
                }
            } else {
                return AjaxResult.error("设备不存在！");
            }
        } else {
            return AjaxResult.error("设备对应产品不存在！");
        }
    }

    /**
     * 修改设备断电时间
     */
    @PreAuthorize("@ss.hasPermi('device:device:edit')")
    @Log(title = "设备管理", businessType = BusinessType.UPDATE)
    @PutMapping("/editDdtime")
    public AjaxResult editDdtime(@Validated @RequestBody IotDevice device)
    {
        IotProduct product = productService.selectProductById(device.getProductId());
        if (StringUtils.isNotNull(product)) {
            IotDevice existDevice = deviceService.selectDeviceByDeviceName(device.getDeviceName());
            if (StringUtils.isNotNull(existDevice)) {
                if (IoTConstants.DEVICE_ONLINE.equals(existDevice.getStatus())) {
                    try {
                        // 使用腾讯云物联网开发平台发布消息
                        Map message = new HashMap();
                        message.put("method", "wifi_attr_cmd");
                        if (StringUtils.isNotNull(device.getCtBeginTime()) && StringUtils.isNotNull(device.getCtEndTime())) {
                            message.put("ddTime", device.getDdTime());
                        }

                        String topic = "$thing/down/property/" + existDevice.getProductId() + "/" + device.getDeviceName();
                        String payload = JSONObject.toJSONString(message);

                        logger.info("业务侧【" + device.getDeviceName() + "】下发【wifi_attr_cmd】消息：" + payload);

                        PublishMessageResponse response = tencentIotService.publishMessage(
                                product.getProductId(), device.getDeviceName(), topic, payload);

                        if (response.getRequestId() != null) {
                            logger.info("业务侧返回【wifi_attr_cmd】消息发送成功");

                            // 执行业务逻辑
                            device.setUpdateBy(getUsername());
                            return toAjax(deviceService.updateDevice(device));
                        } else {
                            return AjaxResult.error("更改房间自动断电时间失败，" + JSON.toJSONString(response));
                        }
                    } catch (Exception e) {
                        return AjaxResult.error("更改房间自动断电时间失败，" + e.getMessage());
                    }
                } else {
                    return AjaxResult.error("设备不在线！");
                }
            } else {
                return AjaxResult.error("设备不存在！");
            }
        } else {
            return AjaxResult.error("设备对应产品不存在！");
        }
    }

    /**
     * 电路开关修改（10扫码开电 11远程通电 12自动通电 01远程断电 02强制断电 03人走断电）
     */
    @Log(title = "设备管理", businessType = BusinessType.UPDATE)
    @PutMapping("/changeCircuitSwitch")
    public AjaxResult changeCircuitSwitch(@RequestBody IotDevice device)
    {
        IotProduct product = productService.selectProductById(device.getProductId());
        if (StringUtils.isNotNull(product)) {
            IotDevice existDevice = deviceService.selectDeviceByDeviceName(device.getDeviceName());
            if (StringUtils.isNotNull(existDevice)) {
                if (IoTConstants.DEVICE_ONLINE.equals(existDevice.getStatus())) {
                    try {
                        // 使用腾讯云物联网开发平台发布消息
                        Map message = new HashMap();
                        message.put("method", "circuit_switch_cmd");
                        message.put("value", device.getCircuitSwitch());

                        String topic = "$thing/down/property/" + existDevice.getProductId() + "/" + device.getDeviceName();
                        String payload = JSONObject.toJSONString(message);

                        logger.info("业务侧【" + device.getDeviceName() + "】下发【circuit_switch_cmd】消息：" + payload);

                        PublishMessageResponse response = tencentIotService.publishMessage(
                                product.getProductId(), device.getDeviceName(), topic, payload);

                        if (response.getRequestId() != null) {
                            logger.info("业务侧返回【circuit_switch_cmd】消息发送成功");

                            device.setUpdateBy(getUsername());
                            int flag = deviceService.updateCircuitSwitch(device);
                            if (flag > 0) {
                                // 新增住客用电对象
                                IotTenantPower tenantPower = new IotTenantPower();
                                tenantPower.setDeviceId(existDevice.getDeviceId());
                                tenantPower.setPowerType(device.getCircuitSwitch());

                                if (StringUtils.isNotEmpty(device.getUnionid())) {
                                    IotTenant tenant = tenantService.selectIotTenantByUnionid(device.getUnionid());
                                    if (StringUtils.isNotNull(tenant)) {
                                        tenantPower.setTenantId(tenant.getTenantId());
                                    }
                                }
                                tenantPower.setCreateBy(getUsername());
                                tenantPowerService.insertIotTenantPower(tenantPower);
                            }
                            return toAjax(flag);
                        } else {
                            return AjaxResult.error("下发指令失败，请联系管理员！" + JSON.toJSONString(response));
                        }
                    } catch (Exception e) {
                        return AjaxResult.error("下发指令失败，请联系管理员！" + e.getMessage());
                    }
                } else {
                    return AjaxResult.error("设备不在线！");
                }
            } else {
                return AjaxResult.error("设备不存在！");
            }
        } else {
            return AjaxResult.error("设备对应产品不存在！");
        }
    }

    /**
     * 扫码开电修改
     */
    @PreAuthorize("@ss.hasPermi('device:device:edit')")
    @Log(title = "设备管理", businessType = BusinessType.UPDATE)
    @PutMapping("/changeScanPoweron")
    public AjaxResult changeScanPoweron(@RequestBody IotDevice device)
    {
        IotProduct product = productService.selectProductById(device.getProductId());
        if (StringUtils.isNotNull(product)) {
            IotDevice existDevice = deviceService.selectDeviceByDeviceName(device.getDeviceName());
            if (StringUtils.isNotNull(existDevice)) {
                if (IoTConstants.DEVICE_ONLINE.equals(existDevice.getStatus())) {
                    device.setUpdateBy(getUsername());
                    return toAjax(deviceService.updateScanPoweron(device));
                } else {
                    return AjaxResult.error("设备不在线！");
                }
            } else {
                return AjaxResult.error("设备不存在！");
            }
        } else {
            return AjaxResult.error("设备对应产品不存在！");
        }
    }

    /**
     * 人走断电修改
     */
    @PreAuthorize("@ss.hasPermi('device:device:edit')")
    @Log(title = "设备管理", businessType = BusinessType.UPDATE)
    @PutMapping("/changeLavePoweroff")
    public AjaxResult changeLavePoweroff(@RequestBody IotDevice device)
    {
        IotProduct product = productService.selectProductById(device.getProductId());
        if (StringUtils.isNotNull(product)) {
            IotDevice existDevice = deviceService.selectDeviceByDeviceName(device.getDeviceName());
            if (StringUtils.isNotNull(existDevice)) {
                if (IoTConstants.DEVICE_ONLINE.equals(existDevice.getStatus())) {
                    try {
                        // 使用腾讯云物联网开发平台发布消息
                        Map message = new HashMap();
                        message.put("method", "leave_poweroff_cmd");
                        message.put("leave_poweroff", device.getLeavePoweroff());

                        String topic = "$thing/down/property/" + existDevice.getProductId() + "/" + device.getDeviceName();
                        String payload = JSONObject.toJSONString(message);

                        logger.info("业务侧【" + device.getDeviceName() + "】下发【leave_poweroff_cmd】消息：" + payload);

                        PublishMessageResponse response = tencentIotService.publishMessage(
                                product.getProductId(), device.getDeviceName(), topic, payload);

                        if (response.getRequestId() != null) {
                            logger.info("业务侧返回【leave_poweroff_cmd】消息发送成功");

                            // 执行业务逻辑
                            device.setUpdateBy(getUsername());
                            return toAjax(deviceService.updateLavePoweroff(device));
                        } else {
                            return AjaxResult.error("更改房间人走断电配置失败，" + JSON.toJSONString(response));
                        }
                    } catch (Exception e) {
                        return AjaxResult.error("更改房间人走断电配置失败，" + e.getMessage());
                    }
                } else {
                    return AjaxResult.error("设备不在线！");
                }
            } else {
                return AjaxResult.error("设备不存在！");
            }
        } else {
            return AjaxResult.error("设备对应产品不存在！");
        }
    }

    @PreAuthorize("@ss.hasPermi('device:device:qrcode')")
    @GetMapping("/qrcode")
    public AjaxResult createQrcode(String deviceName)
    {
        AjaxResult ajax = AjaxResult.success();

        IotDevice existDevice = deviceService.selectDeviceByDeviceName(deviceName);
        if (StringUtils.isNotNull(existDevice)) {
            IotProduct product = productService.selectProductById(existDevice.getProductId());
            IotHotel hotel = hotelService.selectIotHotelByHotelId(existDevice.getHotelId());

            // 获取accessToken
            String accessToken = weixinService.getAccessToken("danjinwulian", danjinIotAppId, danjinIotSecret);
            if (StringUtils.isEmpty(accessToken)) {
                return AjaxResult.error("获取accessToken失败，请重试！");
            }

            // 生成微信二维码
            String qrcodeUrl = weixinService.createQrcode(accessToken, "DeviceName:" + deviceName);
            if (StringUtils.isEmpty(qrcodeUrl)) {
                return AjaxResult.error("生成微信二维码失败，请重试！");
            }

            // 合成二维码图片并上传到七牛
            // 合成二维码图片
            String qrcodeBgUrl = qiniuDomain + "qrcode_bg.jpg";
            String qrcodeImgUrl = new StringBuilder()
                    .append(qrcodeBgUrl).append("?watermark/3")
//                    .append("/text/").append(UrlSafeBase64.encodeToString("欢迎入住" + hotel.getHotelName() + existDevice.getRoomName()))
                    .append("/text/").append(UrlSafeBase64.encodeToString(product.getProductName()))
                    .append("/font/").append(UrlSafeBase64.encodeToString("思源宋体")).append("/fontsize/2000")
                    .append("/fill/").append(UrlSafeBase64.encodeToString("#FFFFFF"))
                    .append("/gravity/North/dy/60")
                    .append("/image/").append(UrlSafeBase64.encodeToString(qrcodeUrl))
                    .append("/gravity/Center/dx/-2/dy/-60/ws/0.55")
                    //.append("/text/").append(UrlSafeBase64.encodeToString(product.getProductName()))
                    //.append("/font/").append(UrlSafeBase64.encodeToString("思源宋体")).append("/fontsize/2300")
                    //.append("/fill/").append(UrlSafeBase64.encodeToString("#FFFFFF"))
                    //.append("/gravity/South/dy/50")
                    .toString();
            System.out.println(qrcodeImgUrl);
            // 上传到七牛
            Configuration cfg = new Configuration();
            UploadManager uploadManager = new UploadManager(cfg);
            Auth auth = Auth.create(qiniuAccessKey, qiniuSecretKey);
            String token = auth.uploadToken(qiniuBucket, deviceName + ".jpg");
            try {
                byte[] erWeiMaImgByte = ImageUtils.readFile(qrcodeImgUrl);

                Response r = uploadManager.put(erWeiMaImgByte, deviceName + ".jpg", token);
                System.out.println(JSON.toJSONString(r));
            } catch (QiniuException e) {
                return AjaxResult.error("上传二维码到七牛失败！" + e.getMessage());
            }

            ajax.put("qrcodeUrl", qiniuDomain + deviceName + ".jpg");
        } else {
            return AjaxResult.error("设备不存在！");
        }

        return ajax;
    }

    /**
     * 上报固定设备
     */
//    @PreAuthorize("@ss.hasPermi('device:device:edit')")
    @GetMapping("/reportFixDevice")
    public AjaxResult reportFixDevice(String deviceName)
    {
        redisCache.deleteObject(CacheConstants.IOT_DEVICE_KEY + deviceName + "_FixDeviceList");

        IotDevice device = deviceService.selectDeviceByDeviceName(deviceName);
        if (StringUtils.isNotNull(device)) {
            IotProduct product = productService.selectProductById(device.getProductId());
            if (StringUtils.isNotNull(product)) {
                if (IoTConstants.DEVICE_ONLINE.equals(device.getStatus())) {
                    // 使用腾讯云物联网开发平台发布消息
                    Map message = new HashMap();
                    message.put("method", "wifi_fe_cmd");
                    message.put("report", 1);

                    String topic = "$thing/down/property/" + device.getProductId() + "/" + device.getDeviceName();
                    String payload = JSONObject.toJSONString(message);

                    logger.info("业务侧【" + device.getDeviceName() + "】下发【wifi_fe_cmd】消息：" + payload);

                    PublishMessageResponse response = tencentIotService.publishMessage(
                            product.getProductId(), device.getDeviceName(), topic, payload);

                    if (response.getRequestId() != null) {
                        logger.info("业务侧返回【wifi_fe_cmd】消息发送成功");

                        return AjaxResult.success();
                    } else {
                        return AjaxResult.error("上报固定设备失败，" + JSON.toJSONString(response));
                    }
                } else {
                    return AjaxResult.error("设备不在线！");
                }
            } else {
                return AjaxResult.error("设备对应产品不存在！");
            }
        } else {
            return AjaxResult.error("设备不存在！");
        }
    }

    @GetMapping("/listFixDevice")
    public TableDataInfo listFixDevice(String deviceName)
    {
        startPage();
        List<Map<String, String>> list = new ArrayList<>();
        List<Map<String, String>> fixDeviceList = redisCache.getCacheObject(CacheConstants.IOT_DEVICE_KEY + deviceName + "_FixDeviceList");
        if (StringUtils.isNotNull(fixDeviceList) && !fixDeviceList.isEmpty()) {
            list = fixDeviceList;
        }
        return getDataTable(list);
    }

    /**
     * 保存固定设备
     */
//    @PreAuthorize("@ss.hasPermi('device:device:edit')")
    @PutMapping("/saveFixDevice")
    public AjaxResult saveFixDevice(@RequestBody IotDevice device)
    {
        IotDevice existDevice = deviceService.selectDeviceByDeviceName(device.getDeviceName());
        if (StringUtils.isNotNull(existDevice)) {
            IotProduct product = productService.selectProductById(existDevice.getProductId());
            if (StringUtils.isNotNull(product)) {
                if (IoTConstants.DEVICE_ONLINE.equals(existDevice.getStatus())) {
                    List<Map<String, String>> cacheFeList = redisCache.getCacheObject(CacheConstants.IOT_DEVICE_KEY + device.getDeviceName() + "_FixDeviceList");

                    List<Map<String, String>> feList = new ArrayList<>();
                    for (Map<String, String> data : cacheFeList) {
                        Map<String, String> feMap = new HashMap<>();

                        feMap.put("mac", data.get("mac"));
                        if (Arrays.asList(device.getMacs()).contains(data.get("mac"))) {
                            feMap.put("flag", "1");
                        } else {
                            feMap.put("flag", "0");
                        }
                        feList.add(feMap);
                    }

                    // 使用腾讯云物联网开发平台发布消息
                    Map message = new HashMap();
                    message.put("method", "wifi_fe_data");
                    message.put("sn", existDevice.getDeviceName());
                    message.put("fe", feList);

                    String topic = "$thing/down/property/" + existDevice.getProductId() + "/" + existDevice.getDeviceName();
                    String payload = JSONObject.toJSONString(message);

                    logger.info("业务侧【" + existDevice.getDeviceName() + "】下发【wifi_fe_data】消息：" + payload);

                    PublishMessageResponse response = tencentIotService.publishMessage(
                            product.getProductId(), existDevice.getDeviceName(), topic, payload);

                    if (response.getRequestId() != null) {
                        logger.info("业务侧返回【wifi_fe_data】消息发送成功");

                        return AjaxResult.success();
                    } else {
                        return AjaxResult.error("保存固定设备失败，" + JSON.toJSONString(response));
                    }
                } else {
                    return AjaxResult.error("设备不在线！");
                }
            } else {
                return AjaxResult.error("设备对应产品不存在！");
            }
        } else {
            return AjaxResult.error("设备不存在！");
        }
    }

    @GetMapping("/checkStatus")
    public AjaxResult checkStatus(String deviceName)
    {
        AjaxResult ajax = AjaxResult.success();

        IotDevice existDevice = deviceService.selectDeviceByDeviceName(deviceName);
        if (StringUtils.isNotNull(existDevice)) {
            IotProduct product = productService.selectProductById(existDevice.getProductId());
            if (StringUtils.isNotNull(product)) {
                try {
                    // 查询腾讯云物联网平台设备状态
                    DescribeDeviceResponse response = tencentIotService.getDeviceDetail(
                            product.getProductId(), existDevice.getDeviceName());

                    if (response != null && response.getDevice() != null) {
                        // 获取设备状态信息
                        Long status = response.getDevice().getStatus();
                        Long enableState = response.getDevice().getEnableState();

                        logger.info("设备 {} 状态查询成功: status={}, enableState={}",
                                deviceName, status, enableState);

                        ajax.put("status", status);
                        ajax.put("enableState", enableState);
                        ajax.put("deviceName", response.getDevice().getDeviceName());
                        ajax.put("productId", response.getDevice().getProductId());

                        // 如果设备在线，记录最后在线时间
                        if (Objects.equals(status, IoTConstants.DEVICE_OFFLINE)) {
                            Long loginTime = response.getDevice().getLoginTime();
                            if (loginTime != null && loginTime > 0) {
                                ajax.put("lastOnlineTime", new Date(loginTime * 1000));
                            }
                        }
                    } else {
                        logger.warn("设备 {} 状态查询失败: 响应数据为空", deviceName);
                        return AjaxResult.error("查询设备状态失败，响应数据为空");
                    }
                } catch (Exception e) {
                    logger.error("查询设备 {} 状态失败: {}", deviceName, e.getMessage(), e);
                    return AjaxResult.error("查询设备状态失败: " + e.getMessage());
                }
            } else {
                return AjaxResult.error("设备对应产品不存在！");
            }
        } else {
            return AjaxResult.error("设备不存在！");
        }

        return ajax;
    }

    /**
     * 获取首页数量
     */
    @PreAuthorize("@ss.hasPermi('device:device:list')")
    @GetMapping("/getIndexCount")
    public AjaxResult getIndexCount()
    {
        AjaxResult ajax = AjaxResult.success();

        ajax.put("productCount", productService.selectProductCount());
        ajax.put("deviceCount", deviceService.selectDeviceCount());
        ajax.put("hotelCount", hotelService.selectIotHotelCount());
        ajax.put("tenantCount", tenantService.selectIotTenantCount());

        return ajax;
    }
}
